﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.Reflection.Metadata;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using ZGRemote.Server.Core.Handler;
using ZGRemote.Server.Core.Models;


namespace ZGRemote.Server.UI.ViewModels
{
    partial class RemoteShellViewModel : RemoteViewModelBase
    {
        private RemoteShellHandler handler;

        private bool disposedValue;

        [ObservableProperty]
        private string command;

        public ObservableCollection<Run> Docs { get; private set; }

        public RemoteShellViewModel(User user) : base(user) 
        {
            Docs = new ObservableCollection<Run>();
            handler = RemoteShellHandler.GetOrCreateInstance(user.UserContext);
            handler.OutputText += OnOutputText;
            handler.OutputError += OnOutputError;
            handler.CreateRemoteShell();
            command = "";
            header = $"{Core.Properties.Resources.RemoteShell}@{user.IP}:{user.Port}";
        }

        [RelayCommand]
        private void DoCommand()
        {
            handler.DoCommand(Command);
            Command = "";
        }

        private void OnOutputText(string text)
        {
            App.Current.Dispatcher.Invoke(() =>
            {
                Run run = new Run()
                {
                    Text = $"{text}\n"
                };
                Docs.Add(run);
            });
        }

        private void OnOutputError(string error)
        {
            App.Current.Dispatcher.Invoke(() =>
            {
                Run run = new Run()
                {
                    Text = $"{error}\n",
                    FontWeight = FontWeights.Bold,
                    Foreground = new SolidColorBrush(Colors.Red)

                };
                Docs.Add(run);
            });
        }

        protected override void Dispose(bool disposing)
        {
            if(disposedValue) return;
            if (disposing) 
            {
                handler.OutputError -= OnOutputError;
                handler.OutputError -= OnOutputText;
                handler?.CloseRemoteShell();
                handler?.ReleaseInstance();
            }
            disposedValue = true;
            base.Dispose(disposing);
        }
    }
}
